

#include "hw/Samsung_20T202DA2JA.h"
#include "hw/RPi_GPIO.h"
#include "hw/PushButton.h"
#include "hw/SwitchButton.h"
#include "Coordinator.h"

#include "util.h"

#include <chrono>

//#include "boost/program_options.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

#define CONFIG_FILE_PATH "../data/config.ini"
#define WIFI_CREDENTIAL_LIST_PATH_DEFAULT "../data/credential_list.xml"


#if 1
int main(int argc, char *argv[]){
    LOG << "-------------------------\nStarting WebRadio " << std::endl;
    
    //load ini file
    std::string credential_path = WIFI_CREDENTIAL_LIST_PATH_DEFAULT;
    boost::property_tree::ptree pt;
    boost::property_tree::ini_parser::read_ini(CONFIG_FILE_PATH, pt);
    credential_path = pt.get<std::string>("WifiCredential.ListPath");
    ////////
    
    //screen
    std::shared_ptr<Samsung_20T202DA2JA> screen(new Samsung_20T202DA2JA(0));
    screen->start();
    
    //button array, used pause/resume sample and save CPU cycles/energy
    std::shared_ptr<std::vector<std::shared_ptr<Button> > > button_vector(new std::vector<std::shared_ptr<Button> >());
    
    std::shared_ptr<Coordinator> coordinator(new Coordinator(screen, button_vector, credential_path));
    
    #if 1
    ////buttons
    //pull up
    std::shared_ptr<PushButton> button_up(new PushButton(GPIO_BUTTON_UP, coordinator, 1, 1));
    button_vector->push_back(button_up);
    //pull up
    std::shared_ptr<PushButton> button_down(new PushButton(GPIO_BUTTON_DOWN, coordinator, 1, 1));
    button_vector->push_back(button_down);
    //no pull
    std::shared_ptr<SwitchButton> switch_aux_small(new SwitchButton(GPIO_AUX_1, coordinator));
    button_vector->push_back(switch_aux_small);
    //no pull
    std::shared_ptr<SwitchButton> switch_aux_big(new SwitchButton(GPIO_AUX_2, coordinator));
    button_vector->push_back(switch_aux_big);
    //pull up
    std::shared_ptr<SwitchButton> switch_onoff(new SwitchButton(GPIO_ONOFF, coordinator, 1));
    button_vector->push_back(switch_onoff);
    //pull up
    std::shared_ptr<SwitchButton> switch_net_mode(new SwitchButton(GPIO_SWITCH_NET_MODE, coordinator, 1));
    button_vector->push_back(switch_net_mode);
    //pull up
    std::shared_ptr<SwitchButton> switch_mode(new SwitchButton(GPIO_SWITCH_MODE, coordinator, 1));
    button_vector->push_back(switch_mode);

    #endif

    coordinator->start();
    
    while (true){
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    LOG << "End World" << std::endl;
    return 0;
}



void gpio_tests(){
    //// tests nes HW ////
    #if 0
    ///relay tests
    RPi_GPIO::exportPin(GPIO_RELAY_0);
    RPi_GPIO::setOutput(GPIO_RELAY_0);
    RPi_GPIO::exportPin(GPIO_RELAY_1);
    RPi_GPIO::setOutput(GPIO_RELAY_1);
    RPi_GPIO::exportPin(GPIO_RELAY_POWER);
    RPi_GPIO::setOutput(GPIO_RELAY_POWER);
    
    RPi_GPIO::exportPin(GPIO_FRONT_LED);
    RPi_GPIO::setOutput(GPIO_FRONT_LED);
    
    //amp power ON
    LOG << "Amp power : on" << endl;
    RPi_GPIO::write(GPIO_RELAY_POWER, 1);
    this_thread::sleep_for(chrono::milliseconds(250));
    
    //input dac
    LOG << "input : DAC" << endl;
    RPi_GPIO::write(GPIO_RELAY_0, 0);
    this_thread::sleep_for(chrono::milliseconds(250));
    RPi_GPIO::write(GPIO_RELAY_1, 1);
    this_thread::sleep_for(chrono::milliseconds(250));
    #endif
    
    #if 0
    //button test
    RPi_GPIO::exportPin(GPIO_AUX_1);
    RPi_GPIO::setInput(GPIO_AUX_1);
    RPi_GPIO::setPulloff(GPIO_AUX_1);
    RPi_GPIO::exportPin(GPIO_AUX_2);
    RPi_GPIO::setInput(GPIO_AUX_2);
    RPi_GPIO::setPulloff(GPIO_AUX_2);
    RPi_GPIO::exportPin(GPIO_ONOFF);
    RPi_GPIO::setInput(GPIO_ONOFF);
    RPi_GPIO::setPullup(GPIO_ONOFF);
    RPi_GPIO::exportPin(GPIO_BUTTON_UP);
    RPi_GPIO::setInput(GPIO_BUTTON_UP);
    RPi_GPIO::setPullup(GPIO_BUTTON_UP);
    RPi_GPIO::exportPin(GPIO_BUTTON_DOWN);
    RPi_GPIO::setInput(GPIO_BUTTON_DOWN);
    RPi_GPIO::setPullup(GPIO_BUTTON_DOWN);
    RPi_GPIO::exportPin(GPIO_SWITCH_ADMIN);
    RPi_GPIO::setInput(GPIO_SWITCH_ADMIN);
    RPi_GPIO::setPullup(GPIO_SWITCH_ADMIN);
    RPi_GPIO::exportPin(GPIO_SWITCH_MODE);
    RPi_GPIO::setInput(GPIO_SWITCH_MODE);
    RPi_GPIO::setPullup(GPIO_SWITCH_MODE);
    #endif
    
    #if 0
    //aux 2
    this_thread::sleep_for(chrono::milliseconds(2500));
    LOG << "input : Aux 2" << endl;
    RPi_GPIO::write(GPIO_RELAY_0, 1);
    this_thread::sleep_for(chrono::milliseconds(250));
    RPi_GPIO::write(GPIO_RELAY_1, 0);
    
    //aux 1
    this_thread::sleep_for(chrono::milliseconds(2500));
    LOG << "input : Aux 1" << endl;
    RPi_GPIO::write(GPIO_RELAY_0, 0);
    this_thread::sleep_for(chrono::milliseconds(250));
    RPi_GPIO::write(GPIO_RELAY_1, 0);
    
    ////screen + led + buttons
    std::shared_ptr<Samsung_20T202DA2JA> screen(new Samsung_20T202DA2JA(0));
    screen->start();
    
    for (int i=0; i<10240; i++){
        //led²
        RPi_GPIO::write(GPIO_FRONT_LED, i%2);
        //RPi_GPIO::write(GPIO_RELAY_POWER, i%2);
        //this_thread::sleep_for(chrono::milliseconds(5000));
        
        screen->on();
        screen->clear();
        screen->cursor_home();
        //this_thread::sleep_for(chrono::milliseconds(2000));
        screen->write("testtttttt");
        this_thread::sleep_for(chrono::milliseconds(500));
        screen->write("    <<------->");
        this_thread::sleep_for(chrono::milliseconds(500));
        
        //buttons
        LOG << "Aux 1 :\t" << RPi_GPIO::read(GPIO_AUX_1) << endl;
        LOG << "Aux 2 :\t" << RPi_GPIO::read(GPIO_AUX_2) << endl;
        LOG << "ON OFF :\t" << RPi_GPIO::read(GPIO_ONOFF) << endl;
        LOG << "UP :\t\t" << RPi_GPIO::read(GPIO_BUTTON_UP) << endl;
        LOG << "Down :\t" << RPi_GPIO::read(GPIO_BUTTON_DOWN) << endl;
        LOG << "Admin :\t" << RPi_GPIO::read(GPIO_SWITCH_ADMIN) << endl;
        LOG << "Mode :\t" << RPi_GPIO::read(GPIO_SWITCH_MODE) << endl;
        LOG << "------------------ " << i << endl;
        
        //screen->scroll_on_2nd_line("1234567890123456789012345");
        //this_thread::sleep_for(chrono::milliseconds(10000));
        screen->clear();
        screen->off();
        this_thread::sleep_for(chrono::milliseconds(10));
    }
    #endif
    
}

#endif


















//CURL tests
#if 0
#include <curl/curl.h>
CURL *curl;

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;
}

/* this is how the CURLOPT_XFERINFOFUNCTION callback works */ 
//int xferinfo(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
int xferinfo(void *p, double dltotal, double dlnow, double ultotal, double ulnow)
{
    //struct myprogress *myp = (struct myprogress *)p;
    //CURL *curl = myp->curl;
    double curtime = 0;

    //curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
    LOG << "xferinfo " << dlnow*100/dltotal << "%" << std::endl;
    return 0;
}

int test_libcurl(void)
{
    //CURL *curl;
    CURLcode res;
    FILE* fp;

    curl = curl_easy_init();
    if(curl) {
        LOG << "Curl init" << std::endl;
        fp = fopen("curl_out_download", "wb");

        curl_easy_setopt(curl, CURLOPT_URL, "http://media.radiofrance-podcast.net/podcast09/11739-27.01.2014-ITEMA_20580527-0.mp3");
        /* example.com is redirected, so we tell libcurl to follow redirection */ 
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        
        //progress
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
        curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, xferinfo);
        //curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, 0);
        
        //handle when stalled
        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 100L);
        curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 10);
        
        LOG << "Curl setopt" << std::endl;

        /* Perform the request, res will get the return code */ 
        res = curl_easy_perform(curl);
        /* Check for errors */ 
        if(res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

        /* always cleanup */ 
        curl_easy_cleanup(curl);
        fclose(fp);
    }
return 0;
}
#endif

#if 0
int main(int argc, char *argv[]){
    time_t t;
    time(&t);
    struct tm * timeinfo;
    timeinfo = localtime (&t);
    char buff[80];
    strftime (buff, 80 , "%c", timeinfo);
    LOG << "\n\n-------------------------\nStarting debug " << buff << endl;
    
    /*WebStationDataStore ds("../data/web_station_list.xml");
    ds.load();
    ds.save();
    */
    
    //rss::RssReader r("http://radiofrance-podcast.net/podcast09/rss_11739.xml");
    //rss::RssReader r("http://media.radiofrance-podcast.net/podcast09/11739-27.01.2014-ITEMA_20580527-0.mp3");
    //r.load();
    rss::RssReader r("/home/pi/dev/radiopi/build/rss_14726.xml");
    r.load();
    
    WebFileResource wfr(std::string("http://media.radiofrance-podcast.net/podcast09/11739-27.01.2014-ITEMA_20580527-0.mp3"));
    wfr.download();
    
    int i = 0;
    while(!wfr.dl_finished() && i<4){
        this_thread::sleep_for(chrono::milliseconds(5000));
        LOG << wfr.local_size() * 100 / wfr.total_size() << "%" << std::endl;
        i ++;
    }
    wfr.cancel();
    this_thread::sleep_for(chrono::milliseconds(5000));
    LOG << "END" << std::endl;
    
    
    //test_libcurl();
    return 0;
}
#endif

